﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Windows.Forms;
using Infragistics.Win.UltraWinTree;

namespace DMSClient.General
{
    public partial class AccessGrant : Form
    {
        WSHttpBinding httpBinding = new WSHttpBinding();
        EndpointAddress address = new EndpointAddress(Properties.Settings.Default.Server);
        string pass = "";
        DataSet Objectsds = new DataSet();
        DataTable dtOb = new DataTable("Objectsdt");
        DataTable dtTAB = new DataTable("dtTAB");
        DataTable dtGROUP = new DataTable("dtGROUP");
        DataTable dtObjectsByRole;
        int save = 0;
        string cdRole = "";
        string idRole = "";
        public AccessGrant()
        {
            InitializeComponent();
            httpBinding.MaxReceivedMessageSize = 2147483647;
            httpBinding.MaxBufferPoolSize = 2147483647;
            httpBinding.CloseTimeout = TimeSpan.MaxValue;
            httpBinding.ReceiveTimeout = TimeSpan.MaxValue;
            httpBinding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
            httpBinding.Security.Mode = SecurityMode.None;
         

        }

        private void AccessGrant_Load(object sender, EventArgs e)
        {
           
            bgAccessGrant.RunWorkerAsync();
            estado(false);
           
         }

        private void utObjetos_AfterCheck(object sender, Infragistics.Win.UltraWinTree.NodeEventArgs e)
        {             
           this.VerifyParentNodeCheckState(e.TreeNode);
        }

        private void VerifyNodeChild(UltraTreeNode Node) 
        {
            
            foreach (UltraTreeNode hijos in Node.Nodes) 
            {
                if (Node.CheckedState == CheckState.Checked) 
                     hijos.CheckedState = CheckState.Checked;
                 else
                     hijos.CheckedState = CheckState.Unchecked;
            }

        
        }

        private void VerifyParentNodeCheckState(UltraTreeNode descendantNode)
        {
            //	This method only has relevance for non root-level nodes
            UltraTreeNode parentNode = descendantNode.Parent;
            if (parentNode != null)
            {
                //	Get the nodes collection to which the specified descendantNode belongs
                TreeNodesCollection nodesCollection = descendantNode.ParentNodesCollection;

                //	Iterate the nodes collection and get a count of
                //	the number of checked nodes
                int checkedNodesCount = 0;
                for (int i = 0; i < nodesCollection.Count; i++)
                {
                    UltraTreeNode node = nodesCollection[i];

                    if (node.CheckedState == CheckState.Checked)
                        checkedNodesCount++;                   

                }

                //	If all the child nodes are checked, set the parent's CheckState
                //	to 'Checked'; if none are checked then set the parent's CheckState
                //	to 'Unchecked'; if some but not all are checked, make it 'Indeterminate'.
                if (checkedNodesCount == nodesCollection.Count)
                {
                    parentNode.CheckedState = CheckState.Checked;
                   /* foreach (UltraTreeNode papa in utObjetos.Nodes)
                    {
                        papa.CheckedState = CheckState.Checked;

                        foreach (UltraTreeNode hijos in papa.Nodes)
                        {
                            hijos.CheckedState = CheckState.Checked;

                            foreach (UltraTreeNode nietos in hijos.Nodes)
                            {
                                nietos.CheckedState = CheckState.Checked;

                            }
                        }

                    }*/

                }
                else
                    if (checkedNodesCount != 0)
                    {
                        parentNode.CheckedState = CheckState.Indeterminate;
                        if (parentNode.Parent != null)
                        {
                            parentNode.Parent.CheckedState = CheckState.Indeterminate;
                        }
                    }
                    else
                        if (checkedNodesCount > 0)
                            parentNode.CheckedState = CheckState.Indeterminate;
                        else
                            if (checkedNodesCount == 0)
                                // parentNode.CheckedState = CheckState.Unchecked;
                                parentNode.CheckedState = CheckState.Unchecked;
            }
            else 
            {
                 //int hijos = node.GetNodeCount(true);
                     
                 // VerifyNodeChild(descendantNode);
                     
              //  MessageBox.Show(descendantNode.Text);
            
            }
            
           
        }

        private void utObjetos_BeforeCheck(object sender, BeforeCheckEventArgs e)
        {
            	
        }

        private void bgAccessGrant_DoWork(object sender, DoWorkEventArgs e)
        {
            DMSServices.DMSServicesClient cliente = new DMSServices.DMSServicesClient(httpBinding, address);
            string roles;
            string objetos;
            try
            {
                cliente.Open();
                roles = cliente.getRols();
                objetos = cliente.getObjects();
                cliente.Close();
                if (bgAccessGrant.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(Properties.Settings.Default.DistributorsListErrorMsg, ex.InnerException);
            }
            if (roles == null)
            {
                throw new Exception(Properties.Settings.Default.DistributorsNullListErrorMsg);
            }
            if (objetos == null)
            {
                throw new Exception(Properties.Settings.Default.DistributorsNullListErrorMsg);
            }

            DataTable dt = new DataTable("rolesDT");
            dt.Columns.Add("IdRole");
            dt.Columns.Add("cdRole");
            dt.Columns.Add("dsName");
            DataSet ds = new DataSet();
            ds.Tables.Add(dt);


            dtOb.Columns.Add("ObjetoID");
            dtOb.Columns.Add("ObjetoKey");
            dtOb.Columns.Add("ObjetoDescripcion");
            dtOb.Columns.Add("ObjetoTipo");
            dtOb.Columns.Add("ObjetoImagen");
            dtOb.Columns.Add("ObjetoContenedor");
            dtOb.Columns.Add("ObjetoToolType");
            dtOb.Columns.Add("ObjetoIndice");


            Objectsds.Tables.Add(dtOb);


            System.IO.StringReader xmlSR = new System.IO.StringReader(roles);
            ds.ReadXml(xmlSR, XmlReadMode.ReadSchema);

            System.IO.StringReader xmlSRObjects = new System.IO.StringReader(objetos);
            Objectsds.ReadXml(xmlSRObjects, XmlReadMode.ReadSchema);
            
        }

        private void bgAccessGrant_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (!this.IsDisposed)
                {
                    this.BringToFront();
                    MessageBox.Show(this, e.Error.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    estado(true);
                }
            }
            else if (!e.Cancelled && !this.IsDisposed)
            {
                DataTable dtTools = new DataTable();
                dtTools.Columns.Add("ObjetoID");
                dtTools.Columns.Add("ObjetoKey");
                dtTools.Columns.Add("ObjetoDescripcion");
                dtTools.Columns.Add("ObjetoTipo");
                dtTools.Columns.Add("ObjetoImagen");
                dtTools.Columns.Add("ObjetoContenedor");
                dtTools.Columns.Add("ObjetoToolType");
                dtTools.Columns.Add("ObjetoIndice");
                ArrayList lista = new ArrayList();

                
                dtTAB = dtOb.Clone();
                Objectsds.Tables.Add("dtTAB");

                
                dtGROUP = dtOb.Clone();
                Objectsds.Tables.Add("dtGROUP");

                DataTable dtTOOLS = new DataTable("dtTOOLS");
                dtTOOLS = dtOb.Clone();
                Objectsds.Tables.Add("dtTOOLS");

                foreach (DataRow row in Objectsds.Tables[0].Rows)
                {
                    if (row["ObjetoTipo"].ToString().Equals("TAB"))
                    {
                        DataRow fila;
                        fila = dtTAB.NewRow();
                        fila["ObjetoID"] = row["ObjetoID"].ToString();
                        fila["ObjetoKey"] = row["ObjetoKey"].ToString();
                        fila["ObjetoDescripcion"] = row["ObjetoDescripcion"].ToString();
                        fila["ObjetoTipo"] = row["ObjetoTipo"].ToString();
                        fila["ObjetoImagen"] = row["ObjetoImagen"].ToString();
                        fila["ObjetoContenedor"] = row["ObjetoContenedor"].ToString();
                        fila["ObjetoToolType"] = row["ObjetoToolType"].ToString();
                        fila["ObjetoIndice"] = row["ObjetoIndice"].ToString();
                        dtTAB.Rows.Add(fila);
                    }

                    if (row["ObjetoTipo"].ToString().Equals("GROUP"))
                    {
                        DataRow fila;
                        fila = dtGROUP.NewRow();
                        fila["ObjetoID"] = row["ObjetoID"].ToString();
                        fila["ObjetoKey"] = row["ObjetoKey"].ToString();
                        fila["ObjetoDescripcion"] = row["ObjetoDescripcion"].ToString();
                        fila["ObjetoTipo"] = row["ObjetoTipo"].ToString();
                        fila["ObjetoImagen"] = row["ObjetoImagen"].ToString();
                        fila["ObjetoContenedor"] = row["ObjetoContenedor"].ToString();
                        fila["ObjetoToolType"] = row["ObjetoToolType"].ToString();
                        fila["ObjetoIndice"] = row["ObjetoIndice"].ToString();
                        dtGROUP.Rows.Add(fila);
                    }

                    if (row["ObjetoTipo"].ToString().Equals("TOOL"))
                    {
                        DataRow fila;
                        fila = dtTOOLS.NewRow();
                        fila["ObjetoID"] = row["ObjetoID"].ToString();
                        fila["ObjetoKey"] = row["ObjetoKey"].ToString();
                        fila["ObjetoDescripcion"] = row["ObjetoDescripcion"].ToString();
                        fila["ObjetoTipo"] = row["ObjetoTipo"].ToString();
                        fila["ObjetoImagen"] = row["ObjetoImagen"].ToString();
                        fila["ObjetoContenedor"] = row["ObjetoContenedor"].ToString();
                        fila["ObjetoToolType"] = row["ObjetoToolType"].ToString();
                        fila["ObjetoIndice"] = row["ObjetoIndice"].ToString();
                        dtTOOLS.Rows.Add(fila);
                    }

                }


                foreach (DataRow rowTab in dtTAB.Rows)
                {
                    Infragistics.Win.UltraWinTree.UltraTreeNode Padre = new Infragistics.Win.UltraWinTree.UltraTreeNode();
                    Padre.Key = rowTab["ObjetoID"].ToString();
                    Padre.Text = rowTab["ObjetoDescripcion"].ToString();
                    this.utObjetos.Nodes.Add(Padre);

                    foreach (DataRow rowGroup in dtGROUP.Rows)
                    {
                        if (rowGroup["ObjetoContenedor"].ToString().Equals(rowTab["ObjetoID"].ToString()))
                        {
                            Infragistics.Win.UltraWinTree.UltraTreeNode Hijo = new Infragistics.Win.UltraWinTree.UltraTreeNode();
                            Hijo.Key = rowGroup["ObjetoID"].ToString();
                            Hijo.Text = rowGroup["ObjetoDescripcion"].ToString();
                            Padre.Nodes.Add(Hijo);

                            foreach (DataRow rowTool in dtTOOLS.Rows)
                            {
                                if (rowTool["ObjetoContenedor"].ToString().Equals(rowGroup["ObjetoID"].ToString()))
                                {
                                    Infragistics.Win.UltraWinTree.UltraTreeNode Nieto = new Infragistics.Win.UltraWinTree.UltraTreeNode();
                                    Nieto.Key = rowTool["ObjetoID"].ToString();
                                    Nieto.Text = rowTool["ObjetoDescripcion"].ToString();
                                    Hijo.Nodes.Add(Nieto);
                                }

                            }

                        }

                    }

                }
                this.utObjetos.NodeLevelOverrides[0].NodeStyle = NodeStyle.CheckBoxTriState;
                this.utObjetos.NodeLevelOverrides[1].NodeStyle = NodeStyle.CheckBox;
                this.utObjetos.NodeLevelOverrides[2].NodeStyle = NodeStyle.CheckBox;
                //	Expand the first root level node
                this.utObjetos.Nodes[0].Expanded = true;
                this.utObjetos.Nodes[1].Expanded = true;
                this.utObjetos.Nodes[2].Expanded = true;
                estado(true);
            }
        }

        public void estado(bool estado)
        {
            loader.Visible = !estado;
            ubSave.Enabled = estado;
            utDescription.Enabled = estado;
            utRole.Enabled = estado;
        }

        private void AccessGrant_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (bgAccessGrant.IsBusy)
            {
                bgAccessGrant.CancelAsync();
            }
        }

        private void AccessGrant_Shown(object sender, EventArgs e)
        {
            UbicarLoader();
        }

        private void AccessGrant_Resize(object sender, EventArgs e)
        {
            UbicarLoader();
        }

        private void UbicarLoader() 
        {
            loader.Left = (this.Width - loader.Width) / 2;
            loader.Top = ((this.Height - loader.Height) / 2) - loader.Height;
        
        }

        private void uteUsername_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r') ConsultarRole();
        }

        private void uteUsername_Validated(object sender, EventArgs e)
        {
            ConsultarRole();
        }

        private void ConsultarRole() 
        {
            cdRole = this.utRole.Text;
            if (!cdRole.Equals("") && !WorkerObjectsByRole.IsBusy)
            {
                DesmaracarNodos();
                WorkerObjectsByRole.RunWorkerAsync();
                estado(false);
            }
        }

        private void DesmaracarNodos()
        {
            utDescription.Text = "";
            foreach (UltraTreeNode papa in utObjetos.Nodes)
            {
                papa.CheckedState = CheckState.Unchecked;

                foreach (UltraTreeNode hijos in papa.Nodes)
                {
                    hijos.CheckedState = CheckState.Unchecked;

                    foreach (UltraTreeNode nietos in hijos.Nodes)
                    {
                        nietos.CheckedState = CheckState.Unchecked;

                    }
                }

            }
        }

        private void WorkerObjectsByRole_DoWork(object sender, DoWorkEventArgs e)
        {
            DMSServices.DMSServicesClient cliente = new DMSServices.DMSServicesClient(httpBinding, address);
            string objectsByRole;
            
            try
            {
                cliente.Open();
                objectsByRole = cliente.getObjectsByRole(cdRole);                 
                cliente.Close();
                if (WorkerObjectsByRole.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

            }
            catch (Exception ex)
            {
                throw new Exception(Properties.Settings.Default.DistributorsListErrorMsg, ex.InnerException);
            }
            if (objectsByRole == null)
            {
                throw new Exception(Properties.Settings.Default.DistributorsNullListErrorMsg);
            }
            if (objectsByRole == null)
            {
                throw new Exception(Properties.Settings.Default.DistributorsNullListErrorMsg);
            }

            dtObjectsByRole = new DataTable("ObjectsByRoledt");
            dtObjectsByRole.Columns.Add("idRole");
            dtObjectsByRole.Columns.Add("cdRole");
            dtObjectsByRole.Columns.Add("dsName");
            dtObjectsByRole.Columns.Add("idRole1");
            dtObjectsByRole.Columns.Add("idObjeto");

            DataSet ds = new DataSet();
            ds.Tables.Add(dtObjectsByRole);

            System.IO.StringReader xmlSR = new System.IO.StringReader(objectsByRole);
            ds.ReadXml(xmlSR, XmlReadMode.ReadSchema);
            xmlSR.Close();
        }

        private void WorkerObjectsByRole_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (!this.IsDisposed)
                {
                    this.BringToFront();
                    MessageBox.Show(this, e.Error.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    estado(true);
                }
            }
            else if (!e.Cancelled && !this.IsDisposed)
            {
                try
                {

                    if (dtObjectsByRole.Rows.Count != 0)
                    {
                        utDescription.Text = dtObjectsByRole.Rows[0]["dsName"].ToString();
                        //SE ASIGNA EL IDROLE A LA VARIABLE GLOBAL
                        idRole = dtObjectsByRole.Rows[0]["idRole"].ToString();
                    }
                    else 
                    {
                        idRole = "";
                    }
                    foreach (DataRow row in dtTAB.Rows)
                    {
                        TreeNodesCollection nodesCollection = utObjetos.Nodes[row["ObjetoID"].ToString()].Nodes;//COLECCION DE PADRES

                        for (int i = 0; i < nodesCollection.Count; i++)
                        {
                            UltraTreeNode node = nodesCollection[i];//COLECCION DE HIJOS                            

                            TreeNodesCollection nodesCollectionChild = nodesCollection[i].Nodes;//COLECCION DE HIJOS


                            foreach (DataRow fila in dtObjectsByRole.Rows)
                            {
                                if (node.Key.Equals(fila["idObjeto"].ToString()))
                                {
                                    node.CheckedState = CheckState.Checked;
                                }


                            }

                            for (int j = 0; j < nodesCollectionChild.Count; j++)
                            {
                                UltraTreeNode nodeChild = nodesCollectionChild[j];//COLECCION DE HIJOS   */

                                foreach (DataRow filaHija in dtObjectsByRole.Rows)
                                {
                                    if (nodeChild.Key.Equals(filaHija["idObjeto"].ToString()))
                                    {
                                        nodeChild.CheckedState = CheckState.Checked;
                                    }
                                }
                            }


                        }

                    }



                    utDescription.Focus();
                    estado(true);
                }
                catch (Exception exc) { }
            }
        }

        private void ubSave_Click(object sender, EventArgs e)
        {

            if (validateForm())
            {
                WorkerSave.RunWorkerAsync();
                estado(false);
            }
            
        }

        private bool validateForm() 
        {
            
            if (utRole.Text.Equals(""))
            {
                MessageBox.Show("Please enter Role");
                return false;
            }

            if (utDescription.Text.Equals(""))
            {
                MessageBox.Show("Please enter Description");
                return false;
            }

            return true;        
        }

        private void WorkerSave_DoWork(object sender, DoWorkEventArgs e)
        {
            Dtl.Role role = new Dtl.Role();
            if(idRole.Equals(""))
                role.typeOperation = true;
            else
                role.typeOperation = false;

            role.dsName = utDescription.Text;
            role.cdRole = utRole.Text;
            if (idRole != "")            
                role.idRole = int.Parse(idRole);
            
               

           List<Dtl.RoleGrant> RoleGrant = new List<Dtl.RoleGrant>();
            foreach (UltraTreeNode nodoPapa in utObjetos.Nodes)
            {


                if (nodoPapa.CheckedState == CheckState.Checked || nodoPapa.CheckedState == CheckState.Indeterminate)
                {
                    Dtl.RoleGrant roleGrant = new Dtl.RoleGrant();
                    roleGrant.idRole = role.idRole;
                    roleGrant.idObject = int.Parse(nodoPapa.Key);                    
                    RoleGrant.Add(roleGrant);
                }
                foreach (UltraTreeNode nodoHijo in nodoPapa.Nodes)
                {
                    if (nodoHijo.CheckedState == CheckState.Checked || nodoHijo.CheckedState == CheckState.Indeterminate)
                    {
                        Dtl.RoleGrant roleGrantH = new Dtl.RoleGrant();
                        roleGrantH.idRole = role.idRole;
                        roleGrantH.idObject = int.Parse(nodoHijo.Key);                         
                        RoleGrant.Add(roleGrantH);
                    }
                    foreach (UltraTreeNode nodoNieto in nodoHijo.Nodes)
                    {
                        if (nodoNieto.CheckedState == CheckState.Checked || nodoNieto.CheckedState == CheckState.Indeterminate)
                        {
                            Dtl.RoleGrant roleGrantN = new Dtl.RoleGrant();
                            roleGrantN.idRole = role.idRole;
                            roleGrantN.idObject = int.Parse(nodoNieto.Key);                            
                            RoleGrant.Add(roleGrantN);
                        }
                    }
                
                }

            }
            DMSServices.DMSServicesClient cliente = new DMSServices.DMSServicesClient(httpBinding, address);
            
            try
            {
                cliente.Open();
                save = cliente.setRoleGrant(role, RoleGrant);                
                cliente.Close();

                if (WorkerSave.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(Properties.Settings.Default.DistributorsListErrorMsg, ex.InnerException);
            }
        }

        private void WorkerSave_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            switch (save) 
            {
                case 0:
                    MessageBox.Show("Error saving the record, please try again!", "Access Grant");
                    break;

                case -1:
                    MessageBox.Show("Error saving the record, please try again!", "Access Grant");  
                    break;

                case 1:
                    MessageBox.Show("Successfully saved record!", "Access Grant");
                    break;
            }
            estado(true);
        }
    }
}
